package com.atguigu.tingshu.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.util.MongoUtil;
import com.atguigu.tingshu.model.user.UserListenProcess;
import com.atguigu.tingshu.user.service.UserListenProcessService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.atguigu.tingshu.vo.user.UserListenProcessVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;


import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings({"all"})
public class UserListenProcessServiceImpl implements UserListenProcessService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitService rabbitService;

    @Override
    public BigDecimal getTrackBreakSecond(Long userId, Long trackId) {
//		先设置mongodb中的集合名
        String collectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId);
//		从mongodb里面查找数据对应的数据
//		给find方法的参数进行设置
        Query query =Query.query(Criteria.where("trackId").is(trackId));
//		将对应的参数进行封装
        UserListenProcess mongoTemplateOne = mongoTemplate.findOne(query, UserListenProcess.class, collectionName);
//		因为表中的trackId和userId对应的数据唯一，所以直能查询到一条数据
//		创建一个BigDecimal的对象，去封装返回数据
        BigDecimal bigDecimal = null;
        if (mongoTemplateOne != null) {
//			如果不为空，就代表有数据
//			从中获取到对应的breakSecond数据
            bigDecimal = mongoTemplateOne.getBreakSecond();
        } else {
//			如果为空，就代表之前没有听过，直接返回0.00就行
            bigDecimal = new BigDecimal("0.00");
        }
        return bigDecimal;
    }

    @Override
    public void updateListenProcess(Long userId, UserListenProcessVo userListenProcessVo) {
//		先设置mongodb中的集合名
        String collectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId);
//		从mongodb里面查找数据对应的数据
//		给find方法的参数进行设置
        Query query = Query.query(Criteria.where("trackId").is(userListenProcessVo.getTrackId()));
//		将对应的参数进行封装
        UserListenProcess mongoTemplateOne = mongoTemplate.findOne(query, UserListenProcess.class, collectionName);
//		如果是空，就表示第一次添加
        if (mongoTemplateOne == null) {
//			生成一个新的UserListenProcess对象，并赋值
            mongoTemplateOne = new UserListenProcess();
            BeanUtils.copyProperties(userListenProcessVo, mongoTemplateOne);
            mongoTemplateOne.setCreateTime(new Date());
            mongoTemplateOne.setUpdateTime(new Date());
            mongoTemplateOne.setIsShow(1);
        } else {
//		如果不为空表示有数据，只更新更新时间和breakSecond就可以了
            mongoTemplateOne.setUpdateTime(new Date());
            mongoTemplateOne.setBreakSecond(userListenProcessVo.getBreakSecond());
        }
//		将数据保存到mongodb中
        mongoTemplate.save(mongoTemplateOne, collectionName);
        String key = userId+":"+userListenProcessVo.getTrackId();
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, 1, 1, TimeUnit.HOURS);
        if (flag){
            //		保存玩数据之后，要去更新专辑播放次数和对应音频播放次数
            TrackStatMqVo trackStatMqVo = new TrackStatMqVo();
            trackStatMqVo.setAlbumId(mongoTemplateOne.getAlbumId());
            trackStatMqVo.setTrackId(mongoTemplateOne.getTrackId());
            trackStatMqVo.setStatType(SystemConstant.TRACK_STAT_PLAY);
            trackStatMqVo.setCount(1);
            trackStatMqVo.setBusinessNo(UUID.randomUUID().toString().replaceAll("-", ""));
            try {
                rabbitService.sendMessage(MqConst.EXCHANGE_TRACK, MqConst.ROUTING_TRACK_STAT_UPDATE, JSON.toJSONString(trackStatMqVo));
            } catch (Exception e) {
                e.getMessage();
                redisTemplate.delete(key);
            }
        }
    }

    /**
     * 获取用户最近的收听轨迹
     *
     * @param userId 用户ID，用于查询最近的收听记录
     * @return 包含用户最近收听的专辑ID和曲目ID的Map对象
     */
    @Override
    public Map<String, Object> getLatelyTrack(Long userId) {
        // 初始化一个HashMap用于存储最近的收听信息
        HashMap<String, Object> map = new HashMap<>();

        // 创建一个Query对象，用于构建查询条件
        Query query = new Query();

        // 设置查询条件：按照updateTime字段降序排序，并限制结果数量为1，以获取最近的一条记录
        query.with(Sort.by(Sort.Direction.DESC, "updateTime")).limit(1);

        // 使用mongoTemplate执行查询，获取用户最近的收听记录
        List<UserListenProcess> userListenProcesses = mongoTemplate.find(query, UserListenProcess.class, MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId));

        // 检查查询结果是否非空
        if (userListenProcesses.size() > 0) {
            // 获取最近的收听记录
            UserListenProcess userListenProcess = userListenProcesses.get(0);

            // 将最近收听记录的专辑ID和曲目ID存入map中
            map.put("albumId", userListenProcess.getAlbumId());
            map.put("trackId", userListenProcess.getTrackId());
        }

        // 返回存储最近收听信息的map对象
        return map;
    }
}
